#include <stdio.h>
#include <math.h>

#define pi 3.14159265

void print_vet(double * x, long N)
{
	int i;
	
	for (i = 0; i < N; i++)
		printf("%f ", x[i] );
		
	printf("\n");
}


void print_mat(double * m, long N)
{
	int i, j;
	
	for (i = 0; i < N; i++)
	{
		for (j = 0; j < N; j++)
			printf("%f ", m[i * N + j] );
		
		printf("\n");
	}
}

void DCT(double *X, double *x, long N)
{
  long n, k;
  double mat[N][N];
 
  for(n=0;n<N;n++)
      mat[0][n]=1/sqrt(N);
 
  for(k=1;k<N;k++)
      for(n=0;n<N;n++)
          mat[k][n] =
          	sqrt(2.0/N) *
          	cos( k * pi/(2*N) * (2*n+1) );
 
  printf("Matriz do DCT (VERSAO C):\n");
  print_mat( &mat[0][0], n );
 
  for(k=0;k<N;k++)
      X[k]=0;
 
  for(k=0;k<N;k++)
      for(n=0;n<N;n++)
          X[k] += mat[k][n] * x[n];
}


void IDCT(double *x, double *X, long N)
{
  long n, k;
  double mat[N][N];
 
  for(n=0;n<N;n++)
      mat[0][n]= sqrt(1.0/N);
 
  for(k=1;k<N;k++)
      for(n=0;n<N;n++)
          mat[k][n] = sqrt(2.0/N) * cos(k*(2*n+1)*M_PI/(2.0*N));
 
  printf("Matriz do IDCT (VERSAO C):\n");
  print_mat( &mat[0][0], n );
 
  for(k=0;k<N;k++)
      x[k]=0;
 
  for(k=0;k<N;k++)
      for(n=0;n<N;n++)
          x[k] += mat[n][k] * X[n];
}


int main(int argc, char ** argv)
{
	double entrada[3] = { 1.0, 2.0, 3.0 };
	double saida[3];
	long n = 3;

	printf("Entrada:\n");
	print_vet( entrada, n );
	
	DCT( saida, entrada, n );
	
	printf("Saida:\n");
	print_vet( saida, n );
	
	IDCT( entrada, saida, n );
	
	printf("Saida do IDCT (entrada do DCT): \n");
	print_vet( entrada, n );

	return 0;	
}

